<!--
 * @Author: 宋绍华
 * @Date: 2024-11-12 14:58:02
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2025-01-09 15:25:38
 * @FilePath: \scientific_research_manager_web\src\views\project\components\MyProject\ProjectBudgetHasChange.vue
 * @Description: 项目成员
-->
<template>
  <div px-20px>
    <div class="flex items-center mb-17px mt-24px" v-if="props.showTips">
      <div class="flex items-center color-#4E5969">预算总经费 <div ml-12px><span class="color-#F53F3F">{{
        baseInfo?.projectFunding || '0' }}</span>万元</div>
      </div>
      <div class="flex items-center color-#4E5969 ml-32px ">配套经费 <div ml-12px><span
            class="color-#F53F3F">{{ baseInfo?.subsidiaryFunding || '0' }}</span>万元</div>
      </div>
    </div>
    <div class="mb-16px flex justify-between">
      <div class="color-#86909C text-14px" v-if="props.showTips">
        <span
          v-if="props.projectNature !== projectNatureEnum.projectNatureHorizontal">*请注意！辅助性经费（差旅费、交通费等）原则上不超过总经费30%，劳务费不超过总经费10%。</span>
        <span v-else>*请注意！劳务费不超过到账经费的50%，业务招待费不超过到账经费的15%。</span>
      </div>
      <el-button :class="[props.mode === 'add' ? 'mt-10px' : 'mt-[-32px]']" v-if="props.mode !== 'view'" type="primary"
        @click="addMember">添加</el-button>
    </div>
    <el-table border :summary-method="getSummaries" show-summary :data="tableData" style="width: 100%">
      <el-table-column label="序号" width="48">
        <template #default="scope">
          {{ scope.$index + 1 }}
        </template>
      </el-table-column>
      <el-table-column prop="budgetAccount" label="预算科目">
        <template #default="scope">
          <el-select @change="onAccountChange" v-if="mode !== 'view'" style="width: 136px"
            v-model="scope.row.budgetAccount" placeholder="请选择">
            <el-option v-for="dict of budgetList" :disabled="dict.disabled" :key="dict.dataId" :label="dict.dataName"
              :value="dict.dataId" />
          </el-select>
          <span v-else>{{ scope.row.budgetAccountName }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="fundingProportion" label="经费占比">
        <template #default="scope">
          <span v-if="scope.row.fundingProportion">{{ scope.row.fundingProportion }}%</span>
          <span v-else>-</span>
        </template>
      </el-table-column>
      <el-table-column prop="budgetFunding" label="预算经费(万元)">
        <template #default="scope">
          <el-input-number :controls='false' :min="0" :maxlength="10" @change="updateFunding(scope.row)"
            v-if="mode !== 'view'" style="width: 136px" v-model="scope.row.budgetFunding" placeholder="请选择" />
          <span v-else>{{ scope.row.budgetFunding }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="memo" label="备注（计算依据与说明）" width="400px">
        <template #default="scope">
          <el-input v-if="mode !== 'view'" style="width: 336px" v-model="scope.row.memo" :maxlength="2000"
            placeholder="请输入" />
          <span v-else>{{ scope.row.memo }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" v-if="props.mode !== 'view'">
        <template #default="scope">
          <el-button type="danger" link @click="deleteMember(scope.$index)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script lang="ts" setup>
import { FundingCreateApi, getFundingDetailsApi } from '@/api/project';
import { getDicListById } from '../../utils';
import { BaseSuccessRespDTO, DictionaryListRespVO, FundingDTO } from '@/api/project/types';
import { TableColumnCtx } from 'element-plus';
import { projectNatureEnum } from '@/utils/constEnum';

interface SummaryMethodProps<T = DictionaryListRespVO> {
  columns: TableColumnCtx<T>[]
  data: T[]
}

const props = defineProps({
  projectId: {
    type: String,
    default: ''
  },
  dictList: {
    type: Array as PropType<DictionaryListRespVO[]>,
    default: () => []
  },
  mode: {
    type: String as PropType<'add' | 'edit' | 'view'>,
    default: 'add'
  },
  projectNature: {
    type: Number,
    default: 1
  },
  baseInfo: { // 基本信息
    type: Object,
    default: () => { }
  },
  showTips: {
    type: Boolean,
    default: true
  },
  data: {
    type: Array,
    default: () => []
  },
})


onMounted(() => {
  
  if (props.data?.length > 0) {
    tableData.value = props.data
    budgetList.value.forEach((item) => {
      item.disabled = false
    })
    onAccountChange()
  }
})

const tempData = {
  /**
   * 预算科目
   */
  budgetAccount: undefined,
  /**
   * 预算经费（万元）
   */
  budgetFunding: undefined,
  /**
   * 预算占比
   */
  fundingProportion: undefined,
  memo: undefined
}

const tableData = ref([])
const route = useRoute()

const budgetList = computed(() => {
  return getDicListById(21, props.dictList)
})

// 预算经费
const onAccountChange = () => {
  const ids = tableData.value.map(i => i.budgetAccount)
  budgetList.value.forEach((item) => {
    item.disabled = false
  })
  const list = budgetList.value.filter(i => ids.includes(i.dataId))
  list.forEach((item) => {
    item.disabled = true
  })
}

// 添加成员
const addMember = () => {
  tableData.value.push({ ...tempData })
}

const validate = () => {
  return tableData.value.some(i => {
    const isEmpty = Object.keys(i).every(key => {
      if (i[key] === undefined) {
        return false
      }
      return true
    })
    return isEmpty
  })
}

const { runAsync: getFundingDetails } = useRequest(getFundingDetailsApi, {
  manual: true,
  onSuccess: (res) => {
    tableData.value = res
    // 重置列表
    budgetList.value.forEach((item) => {
      item.disabled = false
    })
    if (tableData.value.length > 0) {
      onAccountChange()
    }
  }
})

watch(
  () => [props.mode, props.projectId],
  async () => {
    if (props.data?.length > 0) {
      return
    }
    if (props.mode !== 'add' || props.projectId) {
      await getFundingDetails({ projectId: props.projectId || route.query.projectId })
    }

    // 新增
    if (props.mode === 'add' && tableData.value.length === 0 && props.projectNature !== projectNatureEnum.projectNatureHorizontal) {
      setTimeout(() => {
        addMember()
      }, 400)
    }
  },
  {
    immediate: true
  }
)

// 创建or更新
const { runAsync: coCreate } = useRequest(FundingCreateApi, {
  manual: true,
  onSuccess: (res: BaseSuccessRespDTO, params) => {
    if (res.isSuccess && (params[0].isSave || params[0].isTemp)) {
      ElMessage({
        message: '操作成功',
        type: 'success',
      })
    }

    return res.isSuccess
  }
})

// 创建项目
const create = async (isTemp: boolean = false, isSave: boolean = false) => {
  // 暂存
  if (isTemp) {
    coCreate({ fundingDTOList: tableData.value, isTemp, projectId: props.projectId })
    return true
  }

  const res = await validate()
  // 数据为空，可以直接放过去,横向不需要填写预算
  if (tableData.value.length === 0 && props.projectNature === projectNatureEnum.projectNatureHorizontal) return true
  if (!res) {
    ElMessage.error('请完善内容')
    return false
  } else {
    try {
      // 纵向、校级校验预算总数是否与基本信息的预算总经费一致
      if (props.projectNature !== projectNatureEnum.projectNatureHorizontal) {
        const totalAmount = getFundingProportion(tableData.value)?.toFixed(6)
        console.log(totalAmount, 'totalAmount');

        if (parseFloat(totalAmount) !== props.baseInfo?.projectFunding) {
          ElMessage.error('预算信息中合计与预算总经费经费不一致，请修改后提交。')
          return false
        }
      }
      const res = await coCreate({ fundingDTOList: tableData.value, isTemp, projectId: props.projectId, isSave })
      return res
    } catch (error) {
      console.log(error, 'error');
    }
  }
}

// 计算tableData中的预算经费
const getFundingProportion = (data: FundingDTO[]) => {
  const fundingProportion = data.reduce((prev, curr) => {
    const value = Number(curr.budgetFunding)
    if (!Number.isNaN(value)) {
      return Number(prev) + Number(curr.budgetFunding)
    } else {
      return Number(prev)
    }
  }, 0)
  return fundingProportion
}

// 更新当前行的预算经费，并计算出其他行的经费占比，更新表格数据
const updateFunding = () => {
  const fundingTotal = getFundingProportion(tableData.value)
  let total = 0
  tableData.value.forEach((item, idx) => {
    if (idx === tableData.value.length - 1) {
      if (total !== 100) {
        item.fundingProportion = (100 - total).toFixed(2)
      } else {
        item.fundingProportion = 0
      }
    } else {
      item.fundingProportion = item?.budgetFunding ? ((Number(item.budgetFunding) / fundingTotal) * 100).toFixed(2) : 0
      total += Number(item.fundingProportion)
    }
  })
}

// 计算出table 的合计，并显示在最后一行，经费占比输出百分比，根据预算经费得出
const getSummaries = (param: SummaryMethodProps) => {
  const { columns, data } = param
  const sums: (string | VNode)[] = []
  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = ''
    } else if (index === 1) {
      sums[index] = '合计'
    } else if (index === 2) {
      sums[index] = '100.00%'
    } else if (index === 3) {
      // 汇总table 中的预算经费
      const _sum = getFundingProportion(tableData.value)
      sums[index] = _sum.toFixed(6)
    }

    return sums
  })

  return sums
}

// 删除成员
const deleteMember = (index: number) => {
  const item = tableData.value[index]
  tableData.value.splice(index, 1)
  const i = budgetList.value.find(i => i.dataId === item.budgetAccount)
  if (i) {
    i.disabled = false
  }
  // 重新计算一遍
  updateFunding()
}

defineExpose({
  create,
  fundingDTOList: tableData,
})
</script>

<style scoped lang='scss'>
:deep(.el-input-number .el-input__inner) {
  text-align: left;
}
</style>